﻿using System;
using UnityEngine;
using System.Collections.Generic;
using System.Text;
using UnityEditor;
using UnityEngine.SceneManagement;
using Debug = UnityEngine.Debug;
using Object = UnityEngine.Object;
using System.Reflection;

namespace SoarDEditor.Pandora
{
    public class PdrEditorHelper : PdrFindHelper
    {
        #region Assets

        public static void ModifyUIPrefabs(string title, GameObjectDelegate action)
        {
            ExcuteAsset(title, GetUIPrefabs(), source =>
            {
                GameObject newGo = PrefabUtility.InstantiatePrefab(source.gameObject) as GameObject;
                if (action(newGo))
                {
                    PrefabUtility.ReplacePrefab(newGo, source.gameObject, ReplacePrefabOptions.ConnectToPrefab);
                }
                Object.DestroyImmediate(newGo);
            });
        }

        public static void CheckAllPrefabs(string title, params Action<AssetObject>[] actions)
        {
            ExcuteAsset(title, GetAllPrefabs(), actions);
        }

        public static void CheckUIPrefabs(string title, params Action<AssetObject>[] actions)
        {
            ExcuteAsset(title, GetUIPrefabs(), actions);
        }

        public static void CheckAllTexture(string title, params Action<AssetObject>[] actions)
        {
            ExcuteAsset(title, GetAllTextures(), actions);
        }
        #endregion

        #region Art
        public static void CheckArtTextures(string title, Action<AssetObject> action)
        {
            ExcuteAsset(title, GetArtTextures(), action);
        }

        public static void CheckArtFBXModel(string title, params Action<AssetObject>[] actions)
        {
            ExcuteAsset(title, GetFbxModels(), actions);
        }

        public static void CheckUISpritesName(string title, params Action<AssetObject>[] actions)
        {
            EditorUtility.DisplayProgressBar(title, "Please Wait......", 0);
            ClearConsole();
            AssetDatabase.Refresh();
            List<AssetObject> list = GetSourceSprites();
            for (int i = 0; i < list.Count; i++)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append(list[i].name).Append("(").Append(i + 1).Append("/").Append(list.Count).Append(")");
                EditorUtility.DisplayProgressBar(title, sb.ToString(), i * 1.0f / list.Count);
                for (int j = i+1; j < list.Count; j++)
                {
                    if (list[i].name==list[j].name)
                    {
                        foreach (var action in actions)
                        {
                            action(list[i]);
                            action(list[j]);
                        }
                    }
                }
            }
            EditorUtility.ClearProgressBar();
        }

        #endregion

        #region Excute Base
        public static void ExcuteAsset(string title, List<AssetObject> list, params Action<AssetObject>[] actions)
        {
            EditorUtility.DisplayProgressBar(title, "Please Wait......", 0);
            ClearConsole();
            AssetDatabase.Refresh();
            for (int i = 0; i < list.Count; i++)
            {
                var source = list[i];
                StringBuilder sb = new StringBuilder();
                sb.Append(source.name).Append("(").Append(i + 1).Append("/").Append(list.Count).Append(")");
                EditorUtility.DisplayProgressBar(title, sb.ToString(), i * 1.0f / list.Count);
                foreach (var action in actions)
                {
                    action(source);
                }
            }
            EditorUtility.ClearProgressBar();
        }

        /// <summary>
        /// 清空Console
        /// </summary>
        public static void ClearConsole()
        {
            // 5.x的方法
            var logEntries = Type.GetType("UnityEditorInternal.LogEntries,UnityEditor.dll");
            // debug下检查括号内条件, 若条件为false。则会显示一个消息框，其中会显示调用堆栈
            System.Diagnostics.Debug.Assert(logEntries != null, "logEntries != null");
            var clearMethod = logEntries.GetMethod("Clear", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
            clearMethod.Invoke(null, null);

            // 2017+的方法
            //Assembly assembly = Assembly.GetAssembly(typeof(SceneView));
            //Type logEntries = assembly.GetType("UnityEditor.LogEntries");
            //System.Diagnostics.Debug.Assert(logEntries != null, "logEntries != null");
            //MethodInfo clearConsoleMethod = logEntries.GetMethod("Clear");
            //clearConsoleMethod.Invoke(new object(), null);
        }

        public static void ExcuteAssetOperat(Action<Object> action, SelectionMode Mode = SelectionMode.Deep)
        {
            ClearConsole();
            Object[] items = Selection.GetFiltered(typeof(Object), Mode);
            foreach (var item in items)
            {
                Debug.Log(item);
                action(item);
            }
            AssetDatabase.Refresh();
            Debug.Log("----------------Finish----------------");
        }
        #endregion

        #region Other

        public static void FindGameObjectInCurrentScene(Action<GameObject> action)
        {
            Scene scene = SceneManager.GetActiveScene();
            GameObject[] arrGO = scene.GetRootGameObjects();
            if (arrGO != null && arrGO.Length > 0)
            {
                for (int i = 0; i < arrGO.Length; i++)
                {
                    action(arrGO[i]);
                }
            }
        }
        #endregion
    }

}
